home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / tnftpsr / tnback.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-17  |  46.9 KB  |  1,766 lines

  1. /*     ANS compatible Telnet in AES windows     */
  2. /*         compiled with TURBO-C/PURE-C         */
  3. /*   P. Mayer & H. Wieser TU Vienna  1992,1993  */
  4.  
  5. #define NET
  6.  
  7. #include <aes.h>            
  8. #include <vdi.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <errno.h>
  12. #include <tos.h>
  13. #include <stdlib.h>
  14. #include <ext.h>
  15. #include "tnftp.h"    /* output from RCS */
  16. #include "tndefs.h"    /* various definitions */
  17. #include "tcpdef.h"    /* tcp layer defs */
  18.  
  19. #ifdef SYSFONTS
  20.   #include <linea.h>
  21. #endif
  22.  
  23. #define TELNET_PORT     23
  24. #define FTP_CTL     21
  25. #define FTP_DATA     20
  26.  
  27. #define XFTP     0
  28. #define TN     1
  29. #define FTP     2
  30.  
  31. #define VERSION "1.33"
  32.  
  33. extern int ftpinit(struct wi_str *wp, char *user, char *passwd);
  34. extern int ftp_application(struct wi_str *);
  35. extern void handle_key(struct wi_str *, char key);
  36. int do_multi(int mode);
  37. void newopen(void);
  38.  
  39. char hostname[MAXPARLEN], user[MAXPARLEN], passwd[MAXPARLEN];
  40. int ftp_ctl, ftp_data;
  41. int linepos;
  42. char keeppath[MAXPATH];
  43. extern int ftpbusy;
  44.  
  45. int work_in[11];
  46. int work_out[57];
  47. int pxyarray[20];
  48. int msgbuff[8];
  49. char line[MAXCOL * MAXROW + 1];
  50. int len;
  51.  
  52. int phys_handle, screen_handle;
  53. int ncolors;              /* used by ESCb and ESCc */
  54. int active, menu_id, appl_id;      /* used to indicate opened ACC */
  55. #ifndef NET
  56.   char buf[1000];
  57. #endif
  58.  
  59. /* evnt_multi data return spaces */
  60. long dummy;
  61. int sdummy;
  62. int key;
  63. #ifdef SYSFONTS
  64.   extern FONTS *Fonts;
  65. #endif
  66.  
  67. /*
  68.  * Character stuff (fonts).
  69.  */
  70. FNT    *fnttbl[10];      /* List of pointers to fonts avail */
  71. int    fontsavail;      /* Number of fonts available */
  72. FNT    *tempfont;      /* font pointer */
  73. int    fntnum = 1;    /* index of font in fonttable */
  74.  
  75. int fontmenuobj[] = 
  76. {  /* array of font menu object numbers */
  77.   FNT8X8,
  78.   FNT8X16,
  79.   FNT6X7,
  80.   FNTOWN,
  81.   FNTALT,
  82.   FNTTNY,
  83.   FNTOTH,
  84.   /* Add new font menu items here! */
  85.   0
  86. };
  87.  
  88. OBJECT *menubar;  /* used in startup & finish */
  89.  
  90. char *caps_table;  /* keyboard table for caps-locked keys (sigh) */
  91.  
  92. /* "fast" controls "window flourish" (grow/shrink boxes) */
  93. int fast = 1;
  94.  
  95. /*
  96.  * jerky_updates controls whether or not you get an update before each
  97.  * non-printing character in the output stream.  With it on things are
  98.  * faster; with it off, things are smoother.
  99.  */
  100. int jerky_updates = 1;
  101.  
  102. /*
  103.  * mouseflicker controls just that: with it ON, the mouse flickers, but
  104.  * it is almost always visible: it gets turned off before redraws and
  105.  * immediately turned on afterwards.  With it OFF, the mouse is turned
  106.  * off before a redraw, then left off until it moves (or you quit or close
  107.  * the last window).
  108.  */
  109. int mouseflicker = 1;
  110.  
  111. int sliders = 0;            /* set by menu items, arguments to w_open */
  112. int titles = 1;
  113. int xsiz, ysiz;
  114. int last_x = 132, last_y = 24;  /* last size you asked for in SHELLOTH */
  115. int audibell, visibell;  /* what to do on bell */
  116. int mouse;  /* visibility flag for mouse */
  117.  
  118. /*
  119.  * globals imported by winsubr
  120.  */
  121.  
  122. struct wi_str *wlist, *wsource;  /* a pointer into the window ring */
  123.  
  124. int scr_x, scr_y, scr_w, scr_h, wnum;  /* screen workxywh (?) */
  125. WIN_MFDB screen_mf;  /* mfdb for the screen */
  126. FNT *curfont;  /* ptr to current font (internal format(?)) */
  127. extern char data[];
  128.  
  129. extern char *getmem();  /* in winsubr.c */
  130.  
  131. /*
  132.  * Resource file first/last objects in menu bar. These have to be the first
  133.  * & last (numerically) which are allowed to have hot-keys assigned to
  134.  * them.  "About ..." is a poor choice since the items after that in the
  135.  * resource are the space-holders for the accessories.  So you can't bind
  136.  * a key to About... So what?  Big deal.
  137.  */
  138.  
  139. #define FIRSTOBJ DABOUT
  140. #define STARTOBJ MENUEDIT
  141. #define LASTOBJ REFONT
  142.  
  143. extern void loadfont (char *);
  144. extern void startup(void);
  145. extern void finish(void);
  146. extern int get_pipe(char *, int *, int *);
  147. extern int s_dial(int, int);
  148. extern void set_menu_string(char *, int);
  149. extern int size_dial(int *, int *);
  150. extern int xatoi(char *);
  151. extern void do_editkeys(void);
  152. extern char *getmem(long size);
  153. extern int w_open(char *name, int xpos, int ypos, int xsiz, int ysiz, int sliders, int titles, FNT *usefont);
  154. extern void w_closei(struct wi_str *wp);
  155. extern void w_close(struct wi_str *wp);
  156. extern int w_resize(struct wi_str *wp1, int xsiz, int ysiz, int sliders, int titles, int chfont);
  157. extern void w_rename(struct wi_str *wp, char *name);
  158. extern void w_info(struct wi_str *wp, char *name);
  159. extern void w_redraw(struct wi_str *wp, int logic, int xx, int yy, int ww, int hh);
  160. extern void w_update(struct wi_str *wp, int logic, int xx, int yy, int ww, int hh);
  161. extern void w_move(struct wi_str *wp, int xx, int yy, int ww, int hh);
  162. extern void w_top(struct wi_str *wp);
  163. extern void w_bottom(void);
  164. extern void w_hide(void);
  165. extern void w_shrink(struct wi_str *wp);
  166. extern void w_full(struct wi_str *wp);
  167. extern void w_arrow(struct wi_str *wp, int arrow);
  168. extern void w_slide(struct wi_str *wp, int hor, int val);
  169. extern void sethslide(struct wi_str *wp);
  170. extern void w_output(struct wi_str *wp, unsigned char *ptr, short charcount);
  171. extern void lineerase(register struct wi_str *wp, int first, int last);
  172. extern void setvslide(struct wi_str *wp);
  173. extern void w_flash(struct wi_str *wp, int state);
  174. extern void scrollup(register struct wi_str *wp, int first, int nlines, int amount);
  175. extern void scrolldn(register struct wi_str *wp, int first, int nlines, int amount);
  176. extern int upcall(struct wi_str *wp);
  177. extern int tnet(struct wi_str *wp, long key);
  178. extern int connect(int port, char * host, int tcp_id);
  179. extern void printw(struct wi_str *wp, char * text);
  180. int get_string(char *prompt, char *string);
  181. int get_host(char *prompt, char *string);
  182. void invert(struct wi_str *wp,int x1,int y1,int x2, int y2);
  183. char char_at(struct wi_str *wp, int x_loc, int y_loc);
  184. extern int tcp_out(int tcp_id, char *o_str, int o_len);
  185.  
  186. /* read a font from a file */
  187. void loadfont (name)
  188. char *name;
  189. {
  190.   FNT * curfont;
  191.   char *tmpfnt;
  192.   char menustr[20];
  193.   char namestr[20];
  194.   int shift;
  195.   unsigned int mask;
  196.   int i;
  197.   char *getmem();
  198.   char x1,x2;
  199.   
  200.   if ((curfont = (FNT *) getmem((long)sizeof(FNT))) == NULL)
  201.     return;
  202.   i = Fopen(name, 0);
  203.   if (i<0) return;
  204.   (void)Fread(i, 4096L, curfont->f_data);
  205.   (void)Fclose(i);
  206.   curfont->inc_x = MINMAX(curfont->f_data[16], 1, 8);
  207.   curfont->inc_y = MINMAX(curfont->f_data[32], 1, 16);
  208.   curfont->nchars = 128;
  209.   curfont->f_data[16] = curfont->f_data[32] = 0;
  210.   shift = 8 - curfont->inc_x;
  211.   mask = (1 << curfont->inc_x) - 1;
  212.   tmpfnt = curfont->f_data;
  213.  
  214.   for (i=0; i < 4096; i++) 
  215.   {
  216.     *tmpfnt = (*tmpfnt>>shift)&mask;
  217.     tmpfnt++;
  218.   }
  219.   if(fontsavail == 1)
  220.   {
  221.     x1 = ALTINDICATOR;
  222.     x2 = 'N';
  223.   }
  224.   else if(fontsavail == 0)
  225.   {
  226.     x1 = ALTINDICATOR;
  227.     x2 = 'L';
  228.   }
  229.   else x1 = x2 = ' ';
  230.   
  231.   if(sscanf(name, "wind%3s", namestr))
  232.   sprintf(menustr, "%d x %2d %s font %c%c", curfont->inc_x, curfont->inc_y,
  233.   namestr,x1,x2);
  234.   else sprintf(menustr, "%d x %2d sys font %c%c", curfont->inc_x, curfont->inc_y,
  235.   x1,x2);
  236.   set_menu_string(menustr, fontmenuobj[fontsavail]);
  237.  
  238.   fnttbl[fontsavail] = curfont;
  239.   fontsavail++;
  240.   return;
  241. }
  242.  
  243. void setfonts(void)
  244. {
  245. #ifdef SYSFONTS
  246.   linea_init();
  247. #endif
  248.        /*
  249.        * now set up the system fonts
  250.        */
  251.   fontsavail = 0;
  252. #ifdef SYSFONTS  
  253.     if ((curfont = (FNT *)getmem((long)sizeof(FNT))) != NULL) 
  254.     {
  255.     tmpfnt = Fonts->font[1]->fnt_dta;    /* 8 x 8 system font */
  256.  
  257.     for (i=0; i<256; i++)
  258.         for (j=0; j<8; j++)
  259.         curfont->f_data[i*16+j] = tmpfnt[i+j*256];
  260.     curfont->inc_x = 8;
  261.     curfont->inc_y = 8;
  262.     curfont->nchars = 256;
  263.  
  264.     set_menu_string("8 x 8 sys font", fontmenuobj[fontsavail]);
  265.  
  266.     fnttbl[fontsavail] = curfont;
  267.     fontsavail++;
  268.     }
  269. #ifdef COPYFONTS
  270.     {
  271.       int fid;
  272.       fid = Fcreate("8x8sys.fnt",0);
  273.       Fwrite(fid,4096L,curfont->f_data);
  274.       Fclose(fid);
  275.     }
  276. #endif
  277.     if ((curfont = (FNT *)getmem((long)sizeof(FNT))) != NULL) 
  278.     {
  279.     tmpfnt = Fonts->font[2]->fnt_dta;    /* 8 x 16 system font */
  280.  
  281.     for (i=0; i<256; i++)
  282.         for (j=0; j<16; j++)
  283.         curfont->f_data[i*16+j] = tmpfnt[i+j*256];
  284.     curfont->inc_x = 8;
  285.     curfont->inc_y = 16;
  286.     curfont->nchars = 256;
  287.  
  288.     set_menu_string("8 x 16 sys font", fontmenuobj[fontsavail]);
  289.  
  290.     fnttbl[fontsavail] = curfont;
  291.     fontsavail++;
  292.     }
  293. #ifdef COPYFONTS
  294.     {
  295.      int fid;
  296.      fid = Fcreate("8x16sys.fnt",0);
  297.      Fwrite(fid,4096L,curfont->f_data);
  298.      Fclose(fid);
  299.     }
  300. #endif
  301.     /* set up 6 x 6 system font */
  302.     if ((curfont = (FNT *)getmem((long)sizeof(FNT))) != NULL) {
  303.     tmpfnt = Fonts->font[0]->fnt_dta;
  304.  
  305.     for (i=0; i<256; i++) 
  306.     {
  307.         int bitpos, index, offset;
  308.  
  309.         bitpos = i * 6;
  310.         index = bitpos >> 3;
  311.         offset = bitpos & ~(~0 << 3);
  312.         for (j=0; j<6; j++) /* for each pixel row in character */
  313.         curfont->f_data[i*16+j+1] = ((tmpfnt[index+j*192] << offset) +
  314.           (tmpfnt[index + j*192 +1] >> (8-offset) & ~(~0 << offset))) /*>> 2 & 0x3f*/;
  315.         curfont->f_data[i*16+0] = 0; /* extra empty row */
  316.     }
  317.     curfont->inc_x = 6;
  318.     curfont->inc_y = 7;
  319.     curfont->nchars = 256;
  320.     /*
  321.      * The 6x6 system font can be made better.  (dot the i and j.)
  322.      * This is a bad hack, but it makes it easier to read.
  323.      */
  324.     curfont->f_data[105*16+1] = 20;
  325.     curfont->f_data[105*16+2] = 0;
  326.     curfont->f_data[105*16+5] = 20;
  327.     curfont->f_data[106*16+5] = 80;
  328.     curfont->f_data[106*16+6] = 20;
  329.     curfont->f_data[106*16+2] = 20;
  330.  
  331.     set_menu_string("6 x 7 sys font", fontmenuobj[fontsavail]);
  332.     fnttbl[fontsavail] = curfont;
  333.     fontsavail++;
  334.     }
  335. #ifdef COPYFONTS
  336.     {
  337.      int fid;
  338.      fid = Fcreate("6x7sys.fnt",0);
  339.      Fwrite(fid,4096L,curfont->f_data);
  340.      Fclose(fid);
  341.     }
  342. #endif
  343. #endif
  344. }
  345.  
  346. void update_help(void)
  347. {
  348. int j = ABOUTTXT;
  349. char *found, *targ;
  350. OBJECT *obj_tmp;
  351. int i;
  352.  
  353.       rsrc_gaddr(R_TREE, HELPTEXT, &obj_tmp);
  354.  
  355.         for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  356.         {
  357.           if(i > FIRSTOBJ && i < STARTOBJ) continue;
  358.           if ((menubar[i].ob_type == G_STRING) &&
  359.            (*(char *)menubar[i].ob_spec.free_string != '-'))
  360.           {
  361.                 found = menubar[i].ob_spec.free_string;
  362.                 targ = obj_tmp[j].ob_spec.free_string;
  363.                 strncpy(targ,found+1,20L);
  364.                 j++;
  365.           }
  366.         }
  367. }
  368.  
  369. void load_settings(void)
  370. {
  371.   FILE *fp;
  372.   int i;
  373.   
  374. fp = fopen("tnftp.inf","r");
  375. if(fp)
  376. {
  377. fscanf(fp,"fast =%d\n",&fast);
  378. fscanf(fp,"jerky =%d\n",&jerky_updates);
  379. fscanf(fp,"mouse =%d\n",&mouseflicker);
  380. fscanf(fp,"sliders =%d\n",&sliders);
  381. fscanf(fp,"titles =%d\n",&titles);
  382. fscanf(fp,"width =%d\n",&last_x);
  383. fscanf(fp,"height =%d\n",&last_y);
  384. fscanf(fp,"audibell =%d\n",&audibell);
  385. fscanf(fp,"visibell =%d\n",&visibell);
  386. fscanf(fp,"font =%d\n",&fntnum);
  387. fscanf(fp,"keys =");
  388. fgetc(fp);
  389.  
  390.         for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  391.         {
  392. char *found;
  393.           if(i > FIRSTOBJ && i < STARTOBJ) continue;
  394.           if ((menubar[i].ob_type == G_STRING) &&
  395.            (*(char *)menubar[i].ob_spec.free_string != '-'))
  396.           { 
  397.                 found = menubar[i].ob_spec.free_string;
  398.                 found = found + strlen(found) - 2;
  399.              fread(found,2,1,fp);
  400.           }
  401.         }
  402. fclose(fp);
  403. }
  404.  
  405. update_help();
  406. }
  407.  
  408. void startup()
  409. {
  410.   int i;
  411. #ifdef SYSFONTS
  412.   int j;
  413.   char *tmpfnt;
  414. #endif
  415.     /* start up everything: appl_init, menu, and the like */
  416.  
  417.   appl_id = appl_init();
  418.   if (!rsrc_load("tnftp.rsc")) 
  419.   {
  420.     form_alert(1,"[1][Can't find resource file!][ Quit ]");
  421.     appl_exit();
  422.     exit(0);
  423.   }
  424.   rsrc_gaddr(R_TREE, MENUBAR, &menubar);
  425.  
  426.   /*
  427.    * set caps_table to the base of the table mapping scan codes to
  428.    * ASCII codes when the CAPS-LOCK key is used.
  429.    */
  430.   caps_table = *(((char **)Keytbl((void*)-1L,(void*)-1L,(void*)-1L))+2);
  431.  
  432.   if(_app) menu_bar(menubar, 1);
  433.  
  434.   /* set mouse symbol to arrow */
  435.   graf_mouse(ARROW, NULL);
  436.   mouse = 1;
  437.  
  438.   /* get screen handle and sizes, open virtual workstation */
  439.   phys_handle = graf_handle(&sdummy, &sdummy, &sdummy, &sdummy);
  440.   wind_get(0, WF_WORKXYWH, &scr_x, &scr_y, &scr_w, &scr_h);
  441.   wnum = scr_y;
  442.   work_in[0] = Getrez() + 2;
  443.   for (i=1; i<10; work_in[i++]=1);
  444.   work_in[10] = 2;
  445.   screen_handle = phys_handle;
  446.   v_opnvwk(work_in, &screen_handle, work_out);
  447.   if (screen_handle == 0) 
  448.   {
  449.     /* out of handles */
  450.     form_alert(1,"[1][Sorry, VDI is out of|workstation handles.][ Quit ]");
  451.     appl_exit();
  452.     exit(1);
  453.   }
  454.  
  455.   /* set up screen mfdb.  Set 'ptr' to NULL and VDI does the rest. */
  456.  
  457.   screen_mf.ptr = NULL;
  458.   ncolors = work_out[13];
  459.       /*
  460.        * Load font file(s) if any.
  461.        */
  462.  
  463.   setfonts();
  464.   
  465.   loadfont("windalt.fnt");
  466.   loadfont("windstd.fnt");
  467.   loadfont("windtny.fnt");
  468.   loadfont("windoth.fnt");
  469. #ifndef SYSFONTS
  470.   loadfont("6x7sys.fnt");
  471.   loadfont("8x8sys.fnt");
  472.   loadfont("8x16sys.fnt");
  473. #endif
  474.   if (fontsavail == 0) 
  475.   {
  476.     /* out of handles */
  477.     form_alert(1,"[1][Sorry, No fontfiles found.][ Quit ]");
  478.     appl_exit();
  479.     exit(1);
  480.   }
  481.   /*
  482.    * Disable unused font entries.
  483.    */
  484.   for (i = fontsavail; fontmenuobj[i] != 0; i++) 
  485.   {
  486.     set_menu_string("unavailable font", fontmenuobj[i]);
  487.     objc_change(menubar, fontmenuobj[i], 0, 0, 0, 0, 0, DISABLED, 0);
  488.   }
  489.   fontmenuobj[fontsavail] = 0;
  490.    load_settings();
  491.   if(!_app) menu_id = menu_register( appl_id, "  Telnet" );
  492. }
  493.  
  494. void finish()
  495. {
  496.   /* close all windows and clean up */
  497.  
  498.   if (!mouse) graf_mouse(M_ON,NULL);
  499.  
  500.   while (wlist) 
  501.   {
  502.     if(wlist->pid)
  503.     {
  504.       tcp_abort(wlist->pid);
  505.       if(wlist->app == FTP)
  506.       {
  507.         if(ftp_data > 0) tcp_abort(ftp_data);
  508.         ftpbusy = ftp_data = 0;
  509.       }
  510.     }
  511.     w_close(wlist);
  512.   }
  513.  
  514.   menu_bar(menubar, 0);
  515.   v_clsvwk(screen_handle);
  516.   appl_exit();
  517.   exit(0);
  518. }
  519.  
  520. static int i;
  521.   int event;
  522.   int menuitem = 0;  /* Alt sequence mapped to menu item */
  523.   int cx, cy, cw, ch;  /* temps used for form_center */
  524. static int mx, my, mb, mk, m2;  /* mouse coordinates from event_multi */
  525.   int clicks;  /* number of clicks seen by evnt_multi. */
  526.   int cnt;
  527.   int tmp;
  528.   OBJECT *obj_tmp;
  529.   TEDINFO *ted_tmp;
  530.   struct wi_str *wp;
  531.   int pastelen;
  532.   
  533.   char *shell;  /* name of shell to start in new windows */
  534.   extern char *getenv();
  535.  
  536. void main(argc,argv)
  537. int argc;
  538. char *argv[];
  539. {
  540.   wsource = NULL;
  541.   len = 0;
  542.   xsiz = 80;
  543.   ysiz = 24;
  544.   fntnum = 1;
  545.   
  546.   startup();
  547.  
  548.   len = 0;
  549.   pastelen = 10000;
  550.   active = 0;
  551.  
  552.   /* set curfont to the standard font and check that menu item */
  553.   if(fntnum < fontsavail) curfont = fnttbl[fntnum];
  554.   else fntnum = 0;
  555.   objc_change(menubar, fontmenuobj[fntnum], 0, 0, 0, 0, 0, CHECKED, 0);
  556.  
  557.   /* initialize mouse flicker and flourish checkmarks to default values */
  558.   menu_icheck(menubar,MFAST, !fast);
  559.   menu_icheck(menubar,MSFLICKR, mouseflicker);
  560.   menu_icheck(menubar,JERKY, jerky_updates);
  561.   menu_icheck(menubar,AUDIBELL, audibell);
  562.   menu_icheck(menubar,VISIBELL, visibell);
  563.   menu_icheck(menubar,TITLES,titles);
  564.   menu_icheck(menubar,SLIDERS,sliders);
  565.  
  566.   if(_app)
  567.   {
  568.     active = 1; 
  569.  
  570.     /* find the name of our shell: the arg, or $DEFHOST, or have to ask for */
  571.  
  572.     shell = NULL;
  573.     if (argc > 1) shell = argv[1];
  574.     else 
  575.     {
  576.       shell = getenv("DEFHOST");
  577.     }
  578.     hostname[0] = 0;
  579.     if(shell) strcpy(hostname,shell);
  580.  
  581.     if (argc > 2) shell = argv[2];
  582.     else 
  583.     {
  584.       shell = getenv("DEFUSER");
  585.     }
  586.     user[0] = 0;
  587.     if(shell) strcpy(user,shell);
  588.     if (argc > 3) shell = argv[3];
  589.     else 
  590.     {
  591.       shell = getenv("DEFPASSWD");
  592.     }
  593.     passwd[0] = 0;
  594.     if(shell) strcpy(passwd,shell);
  595.  
  596.     newopen();
  597.   }
  598.  
  599.   for (;;) 
  600.   {
  601.     do_multi(0);
  602.   }
  603. }
  604.  
  605. /*
  606.  * s_dial performs a simple dialog with buttons and text only.
  607.  * The strchr of the terminating button is returned.
  608.  * If action == 1, the dialog is displayed.  If action == 2, it is
  609.  * removed.  If action == 3, both operations are done and form_do is
  610.  * called.
  611.  */
  612. int s_dial(tree, action)
  613. int tree, action;
  614. {
  615.   int tmp = 0;
  616.   int cx, cy, cw, ch;
  617.   OBJECT *obj_tmp;
  618.  
  619.   rsrc_gaddr(R_TREE, tree, &obj_tmp);
  620.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  621.   if (action & 1) 
  622.   {
  623.     form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  624.     if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  625.     objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  626.   }
  627.   if (action == 3) 
  628.   {
  629.     tmp = form_do(obj_tmp, 0);
  630.   }
  631.   if (action & 2) 
  632.   {
  633.     if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  634.     form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  635.     objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  636.   }
  637.   return (tmp);
  638. }
  639.  
  640. /*
  641.  * set_menu_string sets the menu string for the specified menu object to
  642.  * newstr.
  643.  */
  644. void set_menu_string(newstr, object)
  645. register char * newstr;
  646. int object;
  647. {
  648.   register char * oldstr;
  649.  
  650.   oldstr = (char *) menubar[object].ob_spec.free_string + 2;
  651.   while (*oldstr && *newstr)
  652.     *oldstr++ = *newstr++;
  653.   if (*oldstr)
  654.     *oldstr = ' ';
  655. }
  656.  
  657. int size_dial(pxsiz,pysiz)
  658. int *pxsiz;
  659. int *pysiz;
  660. {
  661.   /*
  662.        * Enter rows and columns dialog
  663.        */
  664.   int cx, cy, cw, ch;
  665.   int xsiz = *pxsiz;
  666.   int ysiz = *pysiz;
  667.   char *rowstr, *colstr;
  668.   int tmp;
  669.   OBJECT *obj_tmp;
  670.   TEDINFO *ted_tmp;
  671.  
  672.   /* show the mouse if it's hidden */
  673.   /* if mouseflicker is ON, "mouse" will never be false. */
  674.   if (!mouse) 
  675.   {
  676.     mouse = 1;
  677.     graf_mouse(M_ON,NULL);
  678.   }
  679.  
  680.   rsrc_gaddr(R_TREE, WINDSIZE, &obj_tmp);
  681.   ted_tmp = (TEDINFO *) obj_tmp[WINDROWS].ob_spec.tedinfo;
  682.   rowstr = ((char *)ted_tmp->te_ptext);
  683.   if (ysiz < 2) ysiz = 2;
  684.   if (xsiz < 2) xsiz = 2;
  685.   if (ysiz > 99) ysiz = 99;
  686.   if (xsiz > 300) xsiz = 300;
  687.   ted_tmp = (TEDINFO *) obj_tmp[WINDCOLS].ob_spec.tedinfo;
  688.   colstr = ((char *)ted_tmp->te_ptext);
  689.   sprintf(rowstr,"%02d",ysiz);
  690.   sprintf(colstr,"%03d",xsiz);
  691.  
  692.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  693.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  694.   if (!fast)
  695.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  696.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  697.   tmp = form_do(obj_tmp, WINDROWS);
  698.   if (!fast)
  699.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  700.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  701.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  702.   if (tmp == WINDCANC)
  703.     return(FALSE);
  704.   xsiz = xatoi(colstr);
  705.   ysiz = xatoi(rowstr);
  706.   if (xsiz < 10)
  707.     xsiz = 10;
  708.   if (xsiz > 300)
  709.     xsiz = 300;
  710.   if (ysiz < 2)
  711.     ysiz = 2;
  712.   if (ysiz > 99)
  713.     ysiz = 99;
  714.   *pxsiz = xsiz;
  715.   *pysiz = ysiz;
  716.   return (TRUE);
  717. }
  718.  
  719. int xatoi(s)
  720. char *s;
  721. {
  722.   int result = 0;
  723.   char c;
  724.  
  725.   while ((c = *s++) != 0) 
  726.   {
  727.     if (c >= '0' && c <= '9') 
  728.     {
  729.       result *= 10;
  730.       result += (c - '0');
  731.     }
  732.     else return result;
  733.   }
  734.   return result;
  735. }
  736.  
  737. void do_editkeys()
  738. {
  739.   /*
  740.        * Enter function-key-edit dialog
  741.        */
  742.   int cx, cy, cw, ch;
  743.   char *namestr, *keystr;
  744.   int tmp;
  745.   OBJECT *obj_tmp;
  746.   TEDINFO *ted_tmp;
  747.   int cycle, direction;
  748.   char *found;
  749.  
  750.   /* show the mouse if it's hidden */
  751.   /* if mouseflicker is ON, "mouse" will never be false. */
  752.   if (!mouse) 
  753.   {
  754.     mouse = 1;
  755.     graf_mouse(M_ON,NULL);
  756.   }
  757.  
  758.   rsrc_gaddr(R_TREE, EDITKEYS, &obj_tmp);
  759.   ted_tmp = (TEDINFO *) obj_tmp[ITEMNAME].ob_spec.tedinfo;
  760.   namestr = ((char *)ted_tmp->te_ptext);
  761.   ted_tmp = (TEDINFO *) obj_tmp[ITEMKEY].ob_spec.tedinfo;
  762.   keystr = ((char *)ted_tmp->te_ptext);
  763.  
  764.   for (cycle = FIRSTOBJ; cycle <= LASTOBJ; cycle++) 
  765.   {
  766.     if(cycle > FIRSTOBJ && cycle < STARTOBJ) continue;
  767.     /* if it's a string & it doesn't start with dash... */
  768.     if (menubar[cycle].ob_type == G_STRING &&
  769.         (*(char *)menubar[cycle].ob_spec.free_string != '-') &&
  770.         !(menubar[cycle].ob_state & DISABLED))
  771.       break;
  772.   }
  773.   if (cycle > LASTOBJ) return;  /* no strings in the menu?! */
  774.   strncpy(namestr,(char *)menubar[cycle].ob_spec.free_string,20);
  775.   if ((found = strchr((char *)menubar[cycle].ob_spec.free_string, ALTINDICATOR)) != NULL) 
  776.   {
  777.     *keystr = *(found+1);
  778.   }
  779.   else *keystr = ' ';
  780.  
  781.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  782.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  783.   if (!fast)
  784.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  785.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  786.   while (1) 
  787.   {
  788.     /* tmp comes back with hi bit set to indicate double-clicks */
  789.     tmp = (form_do(obj_tmp, ITEMKEY) & 0x7fff);
  790.  
  791.     /* (do this regardless of what button you used to get out) */
  792.     /* see if you changed the one you were looking at */
  793.     if (found && *(found+1) != *keystr) 
  794.     {
  795.       /* Had a def'n and you changed it. */
  796.       /* un-set the old meaning */
  797.       if (!*keystr || *keystr == ' ') 
  798.       {
  799.         /* changed to nothing */
  800.         *found = ' ';
  801.         *(found+1) = ' ';
  802.       }
  803.       else 
  804.       {
  805.         /* changed to something */
  806.         *(found+1) = *keystr;
  807.       }
  808.     }
  809.     else if (!found && *keystr && *keystr != ' ') 
  810.     {
  811.       /* didn't have a def'n and you gave one */
  812.       for (found = (char *)menubar[cycle].ob_spec.free_string; *found; found++) ;
  813.       *(--found) = *keystr;
  814.       *(--found) = ALTINDICATOR;
  815.     }
  816.     /* else you didn't change it */
  817.  
  818.     if (tmp != ITEMOK) 
  819.     {
  820.       direction = (tmp == ITEMNEXT ? 1 : -1);
  821.       for (cycle += direction;
  822.          cycle <= LASTOBJ && cycle >= FIRSTOBJ;
  823.          cycle += direction) 
  824.          {
  825.         if(cycle > FIRSTOBJ && cycle < STARTOBJ) continue;
  826.         if (menubar[cycle].ob_type == G_STRING &&
  827.             *(char *)menubar[cycle].ob_spec.free_string != '-')
  828.           break;
  829.       }
  830.       if (cycle > LASTOBJ) cycle = FIRSTOBJ;
  831.       else if (cycle < FIRSTOBJ) cycle = LASTOBJ;
  832.  
  833.       strncpy(namestr,(char *)menubar[cycle].ob_spec.free_string,20);
  834.       if ((found = strchr((char *)menubar[cycle].ob_spec.free_string, ALTINDICATOR)) != NULL)
  835.       {
  836.         *keystr = *(found+1);
  837.       }
  838.       else *keystr = ' ';
  839.  
  840.       /* de-select the "next" button, redraw */
  841.       /* should clip the redraw to the parts that matter */
  842.       objc_change(obj_tmp,ITEMNEXT,0,cx,cy,cw,ch,NORMAL,0);
  843.       objc_draw(obj_tmp,0,5,cx,cy,cw,ch);
  844.     }
  845.     else break;
  846.   }
  847.   if (!fast)
  848.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  849.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  850.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  851.   update_help();
  852. }
  853.  
  854. int get_string(char *prompt, char *string)
  855. {
  856.   int tmp;
  857.   OBJECT *obj_tmp;
  858.   char *ted_tmp;
  859.   int cx, cy, cw, ch;  /* temps used for form_center */
  860.  
  861.   rsrc_gaddr(R_TREE, NEWNAME, &obj_tmp);
  862.   ted_tmp = obj_tmp[PROMPT].ob_spec.free_string;
  863.   strcpy(ted_tmp, prompt);
  864.   strcpy((char*)obj_tmp[FLD1].ob_spec.tedinfo->te_ptext,string);
  865.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  866.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  867.   if (!fast)
  868.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  869.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  870.   tmp = form_do(obj_tmp, FLD1);
  871.   if (!fast)
  872.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  873.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  874.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  875.   if (tmp != OKRENAME) *string = 0;
  876.   else strcpy(string, (char*)obj_tmp[FLD1].ob_spec.tedinfo->te_ptext);
  877.   return tmp;
  878. }
  879.  
  880. int get_host(char *prompt, char *string)
  881. {
  882.   int tmp;
  883.   OBJECT *obj_tmp;
  884.   char *ted_tmp;
  885.   int cx, cy, cw, ch;  /* temps used for form_center */
  886.  
  887.   rsrc_gaddr(R_TREE, NEWCONN, &obj_tmp);
  888.   ted_tmp = obj_tmp[CPROMPT].ob_spec.free_string;
  889.   strcpy(ted_tmp, prompt);
  890.   strcpy((char*)obj_tmp[CFLD1].ob_spec.tedinfo->te_ptext,string);
  891.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  892.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  893.   if (!fast)
  894.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  895.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  896.   tmp = form_do(obj_tmp, CFLD1);
  897.   if (!fast)
  898.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  899.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  900.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  901.   if (tmp != OKFTP && tmp != OKTN) *string = 0;
  902.   else strcpy(string, (char*)obj_tmp[CFLD1].ob_spec.tedinfo->te_ptext);
  903.   return tmp;
  904. }
  905.  
  906. void invert(struct wi_str *wp,int x1,int y1,int x2, int y2)
  907. {
  908.   int t[8];
  909.   int i;
  910.    
  911.   for(i=y1;i<=y2;i++)
  912.   {
  913.     t[0] = t[4] = X0 + wp->m_off;
  914.     t[1] = t[5] = wp->top_y + (wp->font->inc_y * i);
  915.     t[2] = t[6] = t[0] + wp->w - 3*X0;
  916.     t[3] = t[7] = t[1] + wp->font->inc_y - 1;
  917.     if(i==y1) t[0] = t[4] = X0 + wp->m_off + (wp->font->inc_x * x1);
  918.     if(i==y2) t[2] = t[6] = X0 + wp->m_off + (wp->font->inc_x * x2) - 1;
  919.     vro_cpyfm(screen_handle, FM_INVERT, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  920.   }
  921.   w_update(wp, FM_COPY, X0, wp->top_y + (wp->font->inc_y * y1), wp->w, wp->top_y + (wp->font->inc_y * (y2-y1+1)));
  922. }
  923.  
  924. char char_at(struct wi_str *wp, int x_loc, int y_loc)
  925. {
  926.  
  927.   unsigned int width, boffset, count, cur_y, cur_x, i, j;
  928.   register unsigned long mask;
  929.   register unsigned long *dptr;
  930.   register unsigned int shift;
  931.   register FNT *fnt = wp->font;
  932.   static unsigned char pa[32];         /* pixel array containing character image */
  933.   
  934.   cur_x = x_loc * fnt->inc_x + X0;
  935.   cur_y = y_loc * fnt->inc_y + wp->top_y;
  936.   
  937.   width = 2 * wp->wi_mf.wwords;
  938.   boffset = wp->m_off + cur_x + fnt->inc_x - 1;
  939.   dptr = (unsigned long*)(((char*)(wp->wi_mf.ptr)) - 2  + cur_y * width
  940.     + ((boffset >> 4) << 1));
  941.   shift = 15 - (boffset & 15);
  942.   mask = (-1L << (shift + fnt->inc_x)) | ((1 << shift)-1);
  943.   for (count = 0; count < fnt->inc_y; count ++)
  944.   {
  945.     pa[count] = ((*dptr) & (~ mask)) >> shift;
  946.     ((char *) dptr) += width;
  947.   }
  948.   for(i=0;i<fnt->nchars;i++)
  949.   {
  950.    for(j=0;j<fnt->inc_y;j++)
  951.     if(fnt->f_data[i*16 + j] != pa[j]) break;
  952.    if(j == fnt->inc_y) break;
  953.   }
  954.   if(j == fnt->inc_y) return i;
  955.   else
  956.   {
  957.   mask = ~mask >> shift;
  958.   for (count = 0; count < 16; count ++)
  959.   {
  960.     pa[count] = ~pa[count] & mask;
  961.   }
  962.   for(i=0;i<fnt->nchars;i++)
  963.   {
  964.    for(j=0;j<fnt->inc_y;j++)
  965.     if(fnt->f_data[i*16 + j] != pa[j]) break;
  966.    if(j == fnt->inc_y) break;
  967.   }
  968.   if(j == fnt->inc_y) return i;
  969.   else return 0;
  970.   }
  971. }  
  972.  
  973. void save_settings(void)
  974. {
  975.  FILE *fp;
  976.  
  977.  fp = fopen("tnftp.inf","w+");
  978. if(fp)
  979. {
  980. fprintf(fp,"fast = %d\n",fast);
  981. fprintf(fp,"jerky = %d\n",jerky_updates);
  982. fprintf(fp,"mouse = %d\n",mouseflicker);
  983. fprintf(fp,"sliders = %d\n",sliders);
  984. fprintf(fp,"titles = %d\n",titles);
  985. fprintf(fp,"width = %d\n",last_x);
  986. fprintf(fp,"height = %d\n",last_y);
  987. fprintf(fp,"audibell = %d\n",audibell);
  988. fprintf(fp,"visibell = %d\n",visibell);
  989. fprintf(fp,"font = %d\n",fntnum);
  990. fprintf(fp,"keys = ");
  991.  
  992.         for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  993.         {
  994. char *found;
  995.           if(i > FIRSTOBJ && i < STARTOBJ) continue;
  996.           if ((menubar[i].ob_type == G_STRING) &&
  997.            (*(char *)menubar[i].ob_spec.free_string != '-'))
  998.           {
  999.               found = menubar[i].ob_spec.free_string;
  1000.               found = found + strlen(found) - 2;
  1001.            fprintf(fp,"%c%c",*found,*(found+1));
  1002.           }
  1003.         }
  1004. fprintf(fp,"\n");
  1005. fclose(fp);
  1006. }
  1007. else form_alert(1,"[1][Can't write 'tnftp.inf'!][ Quit ]");
  1008. }
  1009.  
  1010. int do_multi(int mode)
  1011. {
  1012.     if (menuitem) 
  1013.     {
  1014.       /* 
  1015.                 * this fork is run when you have faked a menu item with an
  1016.                 * ALT key.  We fall through as if MU_MESAG / MN_SELECTED /
  1017.                 * menuitem came back from AES.
  1018.                 *
  1019.                 * We do not invert any menu titles; below, menu_tnormal
  1020.                 * will not be called because msgbuff[3] contains -1.
  1021.                 */
  1022.       event = MU_MESAG;
  1023.       msgbuff[0] = MN_SELECTED;
  1024.       msgbuff[3] = -1;
  1025.       msgbuff[4] = menuitem;
  1026.       menuitem = 0;
  1027.     }
  1028.     else 
  1029.     {
  1030.       /* if mouseflicker is ON, "mouse" will never be false */
  1031.       if (!mouse) 
  1032.       {
  1033.         if (!wlist) 
  1034.         {
  1035.           /* no windows -- show the mouse */
  1036.           mouse = 1;
  1037.           graf_mouse(M_ON,NULL);
  1038.         }
  1039.         else 
  1040.         {
  1041.           /* get the mouse location so we can wait for it to move */
  1042.           graf_mkstate(&mx,&my,&sdummy,&sdummy);
  1043.         }
  1044.       }
  1045.  
  1046.       /* this is the main event */
  1047.       event = MU_MESAG | MU_KEYBD | MU_BUTTON | MU_TIMER | (mouse ? 0 : MU_M1);
  1048.       event = evnt_multi(event,
  1049.       0x102, 3, 0,
  1050.       1, mx, my, 1, 1,
  1051.       0, 0, 0, 0, 0,
  1052.       msgbuff,
  1053.       10, 0,
  1054.       &mx, &my, &mb, &mk,
  1055.       &key, &clicks);
  1056.     }
  1057.  
  1058.     if(event & MU_BUTTON && wlist)
  1059.     {
  1060.       evnt_timer(100,0);
  1061.       vq_mouse(screen_handle,&m2,&mx,&my);
  1062.       if(mb == 2 && m2 == 0 && len)
  1063.       {
  1064.       /* stuff from buffer */
  1065.         if(wlist->app == TN)
  1066.           tcp_out(wlist->pid,line,len);
  1067.         else pastelen = 0;
  1068.       }
  1069.       else
  1070.       {
  1071.        if(m2 == 0 && wlist->lastx2 >0)
  1072.        {
  1073.        /* if drag finished copy to linebuffer */
  1074.         int x,xend,y,i,printable;
  1075.         char ch;
  1076.  
  1077.         invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2,wlist->marky2);
  1078.         wlist->lastx2 = -1;
  1079.         wsource = wlist;
  1080.         len=0;
  1081.         x = wsource->markx1;
  1082.         for(y = wsource->marky1;y <= wsource->marky2;y++)
  1083.         {
  1084.          i=len;
  1085.          xend = wsource->x_chrs;
  1086.          if(y == wsource->marky2) xend = wsource->markx2-1;
  1087.          for(;x <= xend;x++)
  1088.          {
  1089.            ch = char_at(wsource, x, y);
  1090.            line[i++] = ch;
  1091.          }
  1092.          line[i]=0;
  1093.          printable = 0;
  1094.          while(i > len)
  1095.          {
  1096.            --i;
  1097.            if(line[i]) printable = 1;
  1098.            else if(printable) line[i] = ' ';
  1099.          }
  1100.          len += (int)strlen(&line[len]);
  1101.          if(ch == 0) line[len++] = '\n';
  1102.          x = 0;
  1103.         }
  1104.        }
  1105.        else if(mb == 1)
  1106.        {
  1107.        int x2,y2;
  1108.        
  1109.        pastelen = 10000;
  1110.       
  1111.       if(mx >= wlist->x && mx <= (wlist->x + wlist->w - X0)
  1112.       && my >= wlist->y && my <= (wlist->y + wlist->h - 2*Y0))
  1113.       {
  1114.         x2 = (mx - wlist->x - X0)/wlist->font->inc_x;
  1115.         y2 = (my - wlist->y - Y0)/wlist->font->inc_y;
  1116.  
  1117.         if(x2 != wlist->lastx2 || y2 != wlist->lasty2)
  1118.         {
  1119.           if(wlist->lastx2 >= 0) invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2,wlist->marky2);
  1120.           else
  1121.           {
  1122.             wlist->markx1 = wlist->markx2 = x2;
  1123.             wlist->marky1 = wlist->marky2 = y2;
  1124.           }
  1125.                
  1126.           if(!wlist->direct)
  1127.           {
  1128.            if(y2 > wlist->marky1 || (y2 == wlist->marky1 && x2 > wlist->markx1))
  1129.            {
  1130.             invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2=x2,wlist->marky2=y2);
  1131.             wlist->direct = 0;
  1132.            }
  1133.            else
  1134.            {
  1135.             invert(wlist,wlist->markx1=x2,wlist->marky1=y2,wlist->markx2,wlist->marky2);
  1136.             wlist->direct = 1;
  1137.            }
  1138.           }
  1139.           else
  1140.           {
  1141.            if(y2 < wlist->marky2 || (y2 == wlist->marky2 && x2 < wlist->markx2))
  1142.            {
  1143.             invert(wlist,wlist->markx1=x2,wlist->marky1=y2,wlist->markx2,wlist->marky2);
  1144.             wlist->direct = 1;
  1145.            }
  1146.            else
  1147.            {
  1148.             invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2=x2,wlist->marky2=y2);
  1149.             wlist->direct = 0;
  1150.            }
  1151.           }
  1152.           wlist->lastx2 = x2;
  1153.           wlist->lasty2 = y2;
  1154.           wsource = wlist;
  1155.         }
  1156.       }
  1157.       }
  1158.       }
  1159.     }
  1160.  
  1161.     if (event & MU_M1) 
  1162.     {
  1163.       /* mouse was hidden and moved: show it */
  1164.       mouse = 1;
  1165.       graf_mouse(M_ON,NULL);
  1166.     }
  1167.  
  1168.     if (event & MU_KEYBD) 
  1169.     {
  1170.       /*
  1171.                * Write the key to the pipe of the current window, unless
  1172.                * it's an ALT key that matches a menu item.
  1173.                */
  1174.  
  1175.       unsigned char keyval = key & 0xff;
  1176.       long keystrchr = key >> 8;
  1177.       
  1178. #ifdef NET
  1179. /* lost connection? */      
  1180.       if(active && wlist && wlist->pid == 0)
  1181.       {
  1182.         if(wlist->app == FTP)
  1183.         {
  1184.          if(ftp_data > 0) tcp_abort(ftp_data);
  1185.          ftpbusy = ftp_data = 0;
  1186.         }
  1187.         w_close(wlist);
  1188.       }
  1189.       else
  1190.       {
  1191. /* shortcut or help? */
  1192.        if (active && keyval == 0) 
  1193.        {
  1194.         /* do nothing: setting menuitem is all that's needed. */
  1195.         char * found;
  1196.         int i;
  1197.         if(keystrchr == 0x62)
  1198.         {  /* HELP */
  1199.           s_dial(HELPTEXT,3);
  1200.         }
  1201.         else
  1202.         {
  1203.         menuitem = 0;
  1204.  
  1205.          for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  1206.          {
  1207.           if(i > FIRSTOBJ && i < STARTOBJ) continue;
  1208.           if (menubar[i].ob_type == G_STRING && !(menubar[i].ob_state & DISABLED))
  1209.           {
  1210.             found = strchr(menubar[i].ob_spec.free_string, ALTINDICATOR);
  1211.             if (found != NULL && *(found+1) == caps_table[keystrchr])
  1212.             {
  1213.                  menuitem = i;
  1214.                  break;
  1215.             }
  1216.           }
  1217.          }
  1218.         }
  1219.        }
  1220.        else 
  1221. #endif
  1222.        {
  1223.         if (active && wlist)
  1224.         {
  1225.          if(keyval == 0x13)
  1226.               wlist->recv_flag = 0;
  1227.          if(keyval == 0x11)
  1228.              wlist->recv_flag = 1;
  1229.  
  1230.  
  1231.          if(wlist->app == TN) tnet(wlist, key);
  1232.          else handle_key(wlist, key & 0xff);
  1233.         }
  1234.       }
  1235.     }
  1236.     else if(active && wlist && wlist->app == FTP && pastelen < len)
  1237.     {
  1238.       handle_key(wlist, line[pastelen++]);
  1239.     }
  1240. #ifndef NET
  1241.     {
  1242.  
  1243.       i=0;      
  1244.       while(Bconstat(AUX) && i < 99)
  1245.         buf[i++] = Cauxin() & 0x7f;
  1246.       buf[i]=0;
  1247.       if (wlist && i) 
  1248.       {
  1249.         w_output(wlist,(char *)buf,i);
  1250.         /* else ignore the key (process can't accept output) */
  1251.       }
  1252.       /* else there are no windows, thus nowhere to write to */
  1253.     }
  1254. #endif
  1255. #ifdef NET
  1256.     if (active && wlist)
  1257.     {
  1258.       struct wi_str *wlistsave;
  1259.  
  1260.       wp = wlistsave = wlist;
  1261.  
  1262.       do 
  1263.       {
  1264.         if(wp->pid != 0 && wp->recv_flag)
  1265.         {
  1266.           if(wp->app == TN)
  1267.           {
  1268.             if(upcall(wp) < 0)
  1269.             {
  1270.               tcp_close(wp->pid);
  1271.               w_info(wp,"<Status: connection closed.>");
  1272.               wp->pid = 0;
  1273.             }
  1274.           }
  1275.           else if(wp->app == FTP)
  1276.           {
  1277.             if(ftp_application(wp) == 2)
  1278.             {
  1279.               tcp_abort(wp->pid);
  1280.               if(ftp_data > 0) tcp_abort(ftp_data);
  1281.               w_info(wp,"<Status: connection closed.>");
  1282.               wp->pid = ftpbusy = ftp_data = 0;
  1283.             }
  1284.           }
  1285.         }
  1286.         else tcp_stat(0,NULL);        /* keep network alive */
  1287.         wp = wp->next;
  1288.         if(wlistsave != wlist) wp = wlistsave = wlist;
  1289.       } 
  1290.       while (wlist && wp != wlist);
  1291.     }
  1292.     /*else
  1293.         tcp_stat(0,NULL);*/        /* keep network alive */
  1294. #endif
  1295.  
  1296.     if (event & MU_MESAG) 
  1297.     {
  1298.       switch (msgbuff[0]) 
  1299.       {
  1300.       case MN_SELECTED:
  1301.         switch (msgbuff[4]) 
  1302.         {
  1303.         case MENUEDIT:
  1304.           do_editkeys();
  1305.           break;
  1306.         case WINRESIZ:
  1307.           if (!wlist) break;
  1308.           xsiz = wlist->x_chrs;
  1309.           ysiz = wlist->y_chrs;
  1310.           if (!size_dial(&xsiz,&ysiz)) break;
  1311.           if (w_resize(wlist, xsiz, ysiz, 
  1312.           wlist->sliders, wlist->titles, 0)) 
  1313.           {
  1314.             /* lost the window! Do what we can... */
  1315.           }
  1316.           break;
  1317.  
  1318.           /* "refont" -- reopen the window in the selected font */
  1319.         case REFONT:
  1320.           if (!wlist) break;
  1321.           if (w_resize(wlist, wlist->x_chrs, wlist->y_chrs,
  1322.           wlist->sliders, wlist->titles, 1)) 
  1323.           {
  1324.             /* lost the window! Do what we can... */
  1325.           }
  1326.           break;
  1327.  
  1328.         case FQUIT:
  1329.           if(_app) finish();
  1330.           break;
  1331.  
  1332.         case DABOUT:
  1333.           s_dial(ABOUT, 3);
  1334.           break;
  1335.  
  1336.         case SAVE:
  1337.           save_settings();
  1338.         break;
  1339.                 
  1340.         case LOAD:
  1341.           load_settings();
  1342.         break;
  1343.                 
  1344.         case WRENAME:
  1345.           if (!wlist) break;  /* no window to rename */
  1346.           rsrc_gaddr(R_TREE, NEWNAME, &obj_tmp);
  1347.           ted_tmp = (TEDINFO *) obj_tmp[FLD1].ob_spec.tedinfo;
  1348.           strcpy(ted_tmp->te_ptext, wlist->name);
  1349.           form_center(obj_tmp, &cx, &cy, &cw, &ch);
  1350.           form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  1351.           if (!fast)
  1352.             form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  1353.           objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  1354.           tmp = form_do(obj_tmp, FLD1);
  1355.           if (!fast)
  1356.             form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  1357.           form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  1358.           objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  1359.           if (tmp == OKRENAME)
  1360.             w_rename(wlist, (char *) ted_tmp->te_ptext);
  1361.           break;
  1362.  
  1363.         case JERKY:
  1364.           jerky_updates = !jerky_updates;
  1365.           menu_icheck(menubar,JERKY, jerky_updates);
  1366.           break;
  1367.  
  1368.         case MSFLICKR:
  1369.           mouseflicker = !mouseflicker;
  1370.           menu_icheck(menubar,MSFLICKR, mouseflicker);
  1371.           break;
  1372.  
  1373.         case MFAST:
  1374.           menu_icheck(menubar, MFAST, fast);
  1375.           fast = !fast;
  1376.           break;
  1377.  
  1378.         case FNT8X8:
  1379.         case FNT8X16:
  1380.         case FNT6X7:
  1381.         case FNTOWN:
  1382.         case FNTALT:
  1383.         case FNTTNY:
  1384.         case FNTOTH:
  1385.           /* Add new font menu items here! */
  1386.           for (cnt = 0; fontmenuobj[cnt] != 0; cnt++) 
  1387.           {
  1388.             if (fontmenuobj[cnt] != msgbuff[4]) 
  1389.             {
  1390.               /* un-check any font that isn't the new one */
  1391.               objc_change(menubar, fontmenuobj[cnt],
  1392.               0, 0, 0, 0, 0, NONE, 0);
  1393.             }
  1394.             else 
  1395.             {
  1396.               /* this is the new font: set it & checkmark it */
  1397.                  objc_change(menubar, msgbuff[4],
  1398.                  0, 0, 0, 0, 0, CHECKED, 0);
  1399.                  curfont = fnttbl[cnt];
  1400.                  fntnum = cnt;
  1401.             }
  1402.           }
  1403.           break;
  1404.  
  1405.         case AUDIBELL:
  1406.           audibell = !audibell;
  1407.           objc_change(menubar, AUDIBELL, 0, 0, 0, 0, 0,
  1408.           audibell? CHECKED: 0, 0);
  1409.           break;
  1410.  
  1411.         case VISIBELL:
  1412.           visibell = !visibell;
  1413.           objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0,
  1414.           visibell? CHECKED: 0, 0);
  1415.           break;
  1416.  
  1417.         case SHRNKWIN:  /* Shrink window to iconic size */
  1418.           if (wlist) 
  1419.           {
  1420.             w_shrink(wlist);
  1421.           }
  1422.           break;
  1423.  
  1424.         case BOTTOMTO:  /* send bottom window to top */
  1425.           w_bottom();
  1426.           break;
  1427.  
  1428.         case HIDEWIN:  /* send top window to bottom */
  1429.           w_hide();
  1430.           break;
  1431.  
  1432.         case OSIZEWIN:
  1433.           if (wlist) 
  1434.           {
  1435.             w_full(wlist);
  1436.           }
  1437.           break;
  1438.  
  1439.         case SLIDERS:  /* toggle sliders for new windows */
  1440.           sliders = !sliders;
  1441.           menu_icheck(menubar, SLIDERS, sliders);
  1442.           break;
  1443.  
  1444.         case TITLES:  /* enable/disable window headers */
  1445.           titles = !titles;
  1446.           menu_icheck(menubar, TITLES, titles);
  1447.           break;
  1448.  
  1449.         case SETGADG: 
  1450.           {  /* set gadgets based on settings */
  1451.             if (!wlist) break;
  1452.  
  1453.             if (w_resize(wlist, wlist->x_chrs, wlist->y_chrs,
  1454.             sliders, titles, 0)) 
  1455.             {
  1456.               /* list the window! */
  1457.             }
  1458.             /* make this the "main" style for this window */
  1459.             wlist->wi_mainstyle = wlist->wi_style;
  1460.             break;
  1461.           }
  1462.  
  1463.         case GADGETS: 
  1464.           {  /* toggle gadgets for this window */
  1465.             int tmpslide, tmptitle;
  1466.  
  1467.             if (!wlist) break;
  1468.             /*
  1469.                          * If your original ("main") style includes all sliders,
  1470.                          * this toggles between all and nothing.  Otherwise,
  1471.                          * it toggles between your "main" style and everything.
  1472.                          */
  1473.             if (wlist->wi_mainstyle == (WI_WITHSLD|WI_WITHTITLE)) 
  1474.             {
  1475.               /* main style is full style */
  1476.               if (wlist->wi_style == wlist->wi_mainstyle) 
  1477.               {
  1478.                 /* already all, so make it none */
  1479.                 tmpslide = 0;
  1480.                 tmptitle = 0;
  1481.               }
  1482.               else 
  1483.               {
  1484.                 tmpslide = 1;
  1485.                 tmptitle = 1;
  1486.               }
  1487.             }
  1488.             else if (wlist->wi_style != wlist->wi_mainstyle) 
  1489.             {
  1490.               /* reset back to mainstyle */
  1491.               tmpslide = (wlist->wi_mainstyle & WI_WITHSLD);
  1492.               tmptitle = (wlist->wi_mainstyle & WI_WITHTITLE);
  1493.             }
  1494.             else 
  1495.             {
  1496.               /* add sliders and title bar */
  1497.               tmpslide = 1;
  1498.               tmptitle = 1;
  1499.             }
  1500.             if (w_resize(wlist, wlist->x_chrs, wlist->y_chrs,
  1501.             tmpslide, tmptitle, 0)) 
  1502.             {
  1503.               /* lost the window! Do what we can... */
  1504.             }
  1505.             break;
  1506.           }
  1507.  
  1508.         case SETOTHER:  /* set the "other" size */
  1509.           size_dial(&last_x,&last_y);
  1510.           break;
  1511.  
  1512.         case NEWWIND:  /* new window 24x80*/
  1513.         case NEWOTHER:  /* new other */
  1514.           if (msgbuff[4] == NEWWIND) 
  1515.           {
  1516.             /* default window size */
  1517.             xsiz = 80;
  1518.             ysiz = 24;
  1519.           }
  1520.           else if (msgbuff[4] == NEWOTHER) 
  1521.           {
  1522.             xsiz = last_x;
  1523.             ysiz = last_y;
  1524.           }
  1525.  
  1526.           /* find the name of our shell: the arg, or $SHELL, or MWINIT.PRG */
  1527.  
  1528.           shell = getenv("DEFHOST");
  1529.           if(shell) strcpy(hostname,shell);
  1530.  
  1531.           newopen();
  1532.           break;
  1533.         case CLOSE:
  1534.           if (!wlist) break;
  1535.           if(wlist->pid)
  1536.           {
  1537.            tcp_abort(wlist->pid);
  1538.            if(wlist->app == FTP)
  1539.            {
  1540.              if(ftp_data > 0) tcp_abort(ftp_data);
  1541.              ftpbusy = ftp_data = 0;
  1542.            }
  1543.           } 
  1544.           w_close(wlist);
  1545.           break;
  1546.         }
  1547.         if (msgbuff[3] != -1) menu_tnormal(menubar, msgbuff[3], 1);
  1548.         break;
  1549.  
  1550.       case WM_NEWTOP:
  1551.         /* one of my windows is newly the top window */
  1552.         /* I don't happen to care... Do I? */
  1553.         break;
  1554.  
  1555.       case WM_TOPPED:
  1556.         if (!wlist) break;
  1557.         wp = wlist;
  1558.         do                 
  1559.         {
  1560.           if (wp->aes_handle == msgbuff[3]) 
  1561.           {
  1562.             w_top(wp);
  1563.             break;
  1564.           }
  1565.           wp = wp->next;
  1566.         } 
  1567.         while (wp != wlist);
  1568.         break;
  1569.  
  1570.       case WM_SIZED:
  1571.       case WM_MOVED:
  1572.         if (!wlist) break;
  1573.         wp = wlist;
  1574.         do 
  1575.         {
  1576.           if (wp->aes_handle == msgbuff[3]) 
  1577.           {
  1578.             w_move(wp, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  1579.             break;
  1580.           }
  1581.           wp = wp->next;
  1582.         } 
  1583.         while (wp != wlist);
  1584.         break;
  1585.  
  1586.       case AC_OPEN:
  1587.         if( msgbuff[4] == menu_id )
  1588.         {
  1589.           if (!wlist || active)
  1590.           {
  1591.             /* default window size */
  1592.             xsiz = 80;
  1593.             ysiz = 24;
  1594.  
  1595.             shell = getenv("DEFHOST");
  1596.             if(shell) strcpy(hostname,shell);
  1597.  
  1598.             newopen();
  1599.           }
  1600.           else
  1601.           {
  1602.             if(!active && wlist)
  1603.             {
  1604.               wp = wlist;
  1605.               do 
  1606.               {
  1607.                 int tmp_x, tmp_y, tmp_w, tmp_h;
  1608.                 
  1609.                 wind_calc(0, wp->wi_style, wp->x, wp->y, wp->w, wp->h, &tmp_x, &tmp_y, &tmp_w, &tmp_h);
  1610.                 if (!fast)
  1611.                   graf_growbox(0, 0, 20, 10, tmp_x, tmp_y, tmp_w, tmp_h);
  1612.                 wp->aes_handle = wind_create(wp->wi_style, tmp_x, tmp_y, tmp_w, tmp_h);
  1613.                 if (wp->aes_handle < 0) 
  1614.                 {
  1615.                   form_alert(1, "[1][Sorry, GEM has|no more windows|for us...][Ok]");
  1616.                 }
  1617.                 wind_open(wp->aes_handle, tmp_x, tmp_y, tmp_w, tmp_h);
  1618.                 if (wp->wi_style & NAME) 
  1619.                 {
  1620.                   wind_set(wp->aes_handle, WF_NAME, wp->name, 0, 0);
  1621.                 }
  1622.                 setvslide(wp);
  1623.                 sethslide(wp);
  1624.                 wp = wp->next;
  1625.               } 
  1626.               while (wp != wlist);
  1627.               wlist = wlist->prev;
  1628.             }
  1629.           }
  1630.         }
  1631.         active = 1;
  1632.         break;
  1633.  
  1634.       case AC_CLOSE:
  1635.         if( msgbuff[3] == menu_id )
  1636.         {
  1637.           active = 0;
  1638.         }
  1639.         break;
  1640.  
  1641.       case WM_CLOSED:
  1642.         if (!wlist) break;
  1643.         wp = wlist;
  1644.         do 
  1645.         {
  1646.           if (wp->aes_handle == msgbuff[3]) 
  1647.           {
  1648.             break;
  1649.           }
  1650.           wp = wp->next;
  1651.         } 
  1652.         while (wp != wlist);
  1653.         if(wp->pid)
  1654.         {
  1655.          tcp_abort(wp->pid);
  1656.          if(wlist->app == FTP)
  1657.          {
  1658.            if(ftp_data > 0) tcp_abort(ftp_data);
  1659.            ftpbusy = ftp_data = 0;
  1660.          }
  1661.         }
  1662.         w_close(wp);
  1663.         break;
  1664.  
  1665.       case WM_REDRAW: 
  1666.         {
  1667.           if (!wlist) break;
  1668.           wp = wlist;
  1669.           do 
  1670.           {
  1671.             if (wp->aes_handle == msgbuff[3]) 
  1672.             {
  1673.               w_redraw(wp,FM_COPY, msgbuff[4], msgbuff[5],
  1674.               msgbuff[6], msgbuff[7]);
  1675.               break;
  1676.             }
  1677.             wp = wp->next;
  1678.           } 
  1679.           while (wp != wlist);
  1680.           break;
  1681.         }
  1682.  
  1683.       case WM_FULLED:
  1684.         if (!wlist) break;
  1685.         wp = wlist;
  1686.         do 
  1687.         {
  1688.           if (wp->aes_handle == msgbuff[3]) 
  1689.           {
  1690.             w_full(wp);
  1691.             break;
  1692.           }
  1693.           wp = wp->next;
  1694.         } 
  1695.         while (wp != wlist);
  1696.         break;
  1697.  
  1698.       case WM_ARROWED:
  1699.         if (!wlist) break;
  1700.         wp = wlist;
  1701.         do 
  1702.         {
  1703.           if (wp->aes_handle == msgbuff[3]) 
  1704.           {
  1705.             w_arrow(wp,msgbuff[4]);
  1706.             break;
  1707.           }
  1708.           wp = wp->next;
  1709.         } 
  1710.         while (wp != wlist);
  1711.         break;
  1712.  
  1713.       case WM_HSLID:
  1714.       case WM_VSLID:
  1715.         if (!wlist) break;
  1716.         wp = wlist;
  1717.         do 
  1718.         {
  1719.           if (wp->aes_handle == msgbuff[3]) 
  1720.           {
  1721.             w_slide(wp, msgbuff[0] == WM_HSLID, msgbuff[4]);
  1722.             break;
  1723.           }
  1724.           wp = wp->next;
  1725.         } 
  1726.         while (wp != wlist);
  1727.         break;
  1728.       }
  1729.     }
  1730.     return 0;
  1731. }
  1732.  
  1733. void newopen(void)
  1734. {
  1735.     i = get_host("Hostname:",hostname);
  1736.     if(i == OKFTP || i == OKTN)
  1737.     {
  1738.              if(i != OKFTP || !ftpbusy)
  1739.              {
  1740.               if(i == OKTN) sprintf(data," TUW-Telnet %s (%s) ",VERSION,hostname);
  1741.               else sprintf(data," TUW-Ftp %s (%s) ",VERSION,hostname);
  1742.               wnum += WOFFSET;
  1743.               if(wnum > scr_y+(scr_w/2)) wnum = scr_y;
  1744.  
  1745.               if (w_open(data, wnum, wnum, xsiz, ysiz, sliders, titles, curfont)) 
  1746.               {
  1747.                 /* can't open the window */
  1748.               }
  1749.               else
  1750.               {
  1751.                if(i == OKTN)
  1752.                { 
  1753.                 wlist->pid = connect(0,hostname,TELNET_PORT);
  1754.                 wlist->app = TN;
  1755.                }
  1756.                else
  1757.                {
  1758.                  wlist->app = FTP;
  1759.                  wlist->pid = ftp_ctl = connect(0, hostname,FTP_CTL);
  1760.                  if(ftp_ctl > 0) ftpbusy = 1;
  1761.                  ftpinit(wlist,user,passwd);
  1762.                }               
  1763.               }
  1764.            }
  1765.      }
  1766. }